﻿/****************************************************
	文件：ByteArray.cs
	作者：HuskyT
	邮箱:  1005240602@qq.com
	日期：2020/04/25 0:12   	
	功能：网络消息数据的容器（包含数据操作）
*****************************************************/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace HTClient.Net
{
    public class ByteArray
    {
        /// <summary>
        /// Byte数组的默认大小 = 1024
        /// </summary>
        public const int DEFAULT_SIZE = 1024;
        /// <summary>
        /// 存储数据的Byte数组（数据缓冲）
        /// </summary>
        public byte[] Bytes;
        /// <summary>
        /// （当前）读取数据的索引
        /// </summary>
        public int ReadIndex;
        /// <summary>
        /// （当前）写入数据的索引
        /// </summary>
        public int WriteIndex;
        /// <summary>
        /// 数组容量
        /// </summary>
        public int Capacity;
        /// <summary>
        /// 初始数组容量
        /// </summary>
        public int InitCapacity;
        /// <summary>
        /// 数据长度
        /// </summary>
        public int Length { get { return WriteIndex - ReadIndex; } }
        /// <summary>
        /// 剩余数组空间长度
        /// </summary>
        public int Remain { get { return Capacity - WriteIndex; } }

        public ByteArray()
        {
            InitCapacity = DEFAULT_SIZE;
            Capacity = DEFAULT_SIZE;
            ReadIndex = 0;
            WriteIndex = 0;
            Bytes = new byte[Capacity];
        }
        public ByteArray(byte[] defaultBytes)
        {
            Bytes = defaultBytes;
            InitCapacity = defaultBytes.Length;
            Capacity = defaultBytes.Length;
            ReadIndex = 0;
            WriteIndex = defaultBytes.Length;
        }

        /// <summary>
        /// 检测接收到的数据长度：若小于8，则移动数据到数组起始位置（复用byte数组）
        /// </summary>
        public void CheckAndMoveBytes()
        {
            //copy操作复杂度 o(n) ，只对小数据做 copy 操作
            //Length<8有两种情况：1，数据小；2，数组空间耗尽（Length==0）
            if (Length < 8)
            {
                MoveBytes();
            }
        }
        /// <summary>
        /// 移动数据（移动数据的复杂度为 o(n) ，所以对于大数据不宜copy操作）
        /// </summary>
        public void MoveBytes()
        {
            if (ReadIndex < 0) return;
            Array.Copy(Bytes, ReadIndex, Bytes, 0, Length);
            WriteIndex = Length;
            ReadIndex = 0;
        }
        /// <summary>
        /// 重设Byte数组大小
        /// </summary>
        public void ReSize(int newSize)
        {
            if (ReadIndex < 0) return;
            if (newSize <= Capacity) return;
            if (newSize <= InitCapacity) return;
            while (Capacity < newSize) Capacity *= 2;
            byte[] newBytes = new byte[Capacity];
            Array.Copy(Bytes, ReadIndex, newBytes, 0, Length);
            Bytes = newBytes;
            WriteIndex = Length;
            ReadIndex = 0;//重新开始读
        }
    }
}
